home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Technotools
/
Technotools (Chestnut CD-ROM)(1993).ISO
/
lang_c
/
c_windw
/
dbfdict.c
< prev
next >
Wrap
Text File
|
1987-12-28
|
12KB
|
332 lines
/* (c) Marietta Systems, Inc 1987
* All rights reserved */
/*
* This program sets up the dictionary for a dBase3+ file
*
* The maximum number of fields is 20, and memo fields are not supported
*/
#include "mtest.h"
int dbf_cr(char*);
int dbf_init(int*, struct DBF_DEF*, char*, int);
int dbf_name(byte*);
void linedisp(struct DBF_DEF*, int);
int lineacpt(struct DBF_DEF*, int);
void lineshuf(struct DBF_DEF*, int, int);
#define point "\075\020"
/*
*
* Function to create dbase3+ file & setup data dictionary
*
*/
int dbf_cr(name)
char *name;{
struct DBF_DEF format[20];
int fields = 0, fld = 0, fh = fileopen(name, dbase3, recreate), z, ret;
byte kk = 0;
if (fh < 0) return fh;
/* setup */
for (z = 0; z < 20; format[z++].dbf_type = 'C')
format[z].dbf_name[0] = format[z].dbf_len = format[z].dbf_dec = 0;
/* setup function key map */
KEYMATCH[0] = 0X430; /* Up & right arrow, Ctrl+Enter */
KEYMATCH[1] = 0X108; /* Down & left arrow */
KEYMATCH[2] = KEYMATCH[3] = KEYMATCH[6] = KEYMATCH[7] = 0;
KEYMATCH[4] = 0X3000; /* F5, F6 */
disp_err("",1); /* force display of new function keys */
if (1 > mk_wndw(TOP_LINE + 1, 1, SCRN_LEN - 1, 80,
"Enter data dictionary details for dBase3+ file")) goodbye(13);
kk = INSERT; /* must first insert into an empty dictionary */
linedisp(format, 0);
/* main accept loop */
for(;;){
if (!kk) linedisp(format, fld);
display(point, fld+1, 5, blink);
set_crsr(fld+1, 1);
if (!kk) kk = grabchar();
display(": ", fld+1, 5, high);
switch((int)kk){
case CRS_UP: if (fld) fld--; kk = 0; break;
case CRS_DN: if (fld < 20 && fld < fields) fld++;
kk = 0; break;
case CRS_RT: case ENTER: case TAB:
if (fld == fields) {kk = INSERT; break;}
if ((ret = lineacpt(format, fld)) < 0) goodbye(11);
kk = (ret ? INCHAR : 0);
if (format[fld].dbf_name[0] == 0 && fields != fld)
{lineshuf(format, fld, 1); fields--;}
break;
case QUIT: kk = 0; break;
case INSERT: if (fields >= 20)
{disp_err("No more fields allowed",1); break;}
if (fld < fields) lineshuf(format, fld, -1);
if ((ret = lineacpt(format, fld)) < 0) goodbye(11);
kk = (ret ? INCHAR : 0);
if (format[fld].dbf_name[0] == 0)
lineshuf(format, fld, 1);
else {fld++; fields++;}
if (!kk && fld >= fields - 1) kk = INSERT;
break;
case DELETE:if (fields && fld < fields)
{lineshuf(format, fld, 1); fields--;}
kk = 0; break;
case HELP: if (mk_wndw(3,48,13,80,"Dictionary help") > 1){
display("To change a line, move the ",1,1,high);
display(" cursor with the up and down ",2,1,high);
display(" keys, then make your selec- ",3,1,high);
display(" tion with the Enter key. ",4,1,high);
display("To insert a line press F5 key ",5,1,high);
display("To delete a line press F6 key ",6,1,high);
display("To exit, press the F10 key ",7,1,high);
display("<< Press ESC key to continue>>",9,1,low);
while(grabchar() != ESC)
disp_err("Press ESC key", 2);
rm_wndw();
}
kk = 0; break;
default: warble(1000); idleloop(ERR_BEEP); warble(0);
kk = 0; break;
} /* end switch */
if (INCHAR == QUIT && disp_qry("Have you completed entry"))
break;
} /* end for loop */
ret = ((fields && disp_qry("Write the dictionary to file")) ?
dbf_init(&fh, format, name, fields) : -1);
fileclos(fh); rm_wndw(); return ret;
} /* end function dbf_cr */
/*
*
* Function to write dictionary to new dbase3+ file
*
*/
int dbf_init(fh, format, name, fields)
int *fh, fields;
struct DBF_DEF *format;
char *name;{
int z;
short *sptr;
long rec_nbr = 0L;
fileinit(*fh, 0, 32, 0L); /* nil start, 32 byte record file */
memset(FN[*fh].record, 0, 32);
/* write the system header 32 byte record */
FN[*fh].record[0] = SYS_REC;
sptr = (short *) &FN[*fh].record[8];
sptr[0] = fields * 32 + 33; /* start of data */
for (sptr[1] = 1, z = 0 ; z < fields ; z++)
{sptr[1] += format[z].dbf_len;} /* data record length */
if (filewrit(*fh, &rec_nbr) < 0) goto error;
/* write the field dictionary records */
for (z = 0 ; z < fields ; z++){
memset(FN[*fh].record, 0, 32);
memcpy(FN[*fh].record, format[z].dbf_name, 11);
FN[*fh].record[11] = format[z].dbf_type;
FN[*fh].record[16] = format[z].dbf_len;
FN[*fh].record[17] = format[z].dbf_dec;
if (filewrit(*fh, &rec_nbr) < 0) goto error;
}
/* write the dBase3+ header terminator */
FN[*fh].rec_len = 1; /* hairy but necessary technique here */
FN[*fh].record[0] = 0X0D;
if (filewrit(*fh, &rec_nbr) < 0) goto error;
FN[*fh].rec_len = 32;
FN[*fh].prime = 0L; /* set file record count back to zero */
return 0;
error: fileclos(*fh);
disp_msg("Terminate?? in dbf_init ",(int)rec_nbr + 100); read_kb();
*fh = fileopen(name, dbase3, recreate);
return -1;
} /* end function dbf_init */
/*
*
* Function to display line of data dictionary
*
*/
void linedisp(format, line)
struct DBF_DEF *format;
int line; {
byte text[12];
display("Name: ", line + 1, 1, high);
justify(left, text, format[line].dbf_name, 10, 0);
display(text, 0, 0, ACC_DISP);
display(" Type: ", 0, 0, high);
switch((int)format[line].dbf_type){
case 0:
case 32:
case 'C':display("Character", 0, 0, ACC_DISP); break;
case 'D':display("Date ", 0, 0, ACC_DISP); break;
case 'L':display("Logical ", 0, 0, ACC_DISP); break;
case 'M':display("Memo ", 0, 0, ACC_DISP); break;
case 'N':display("Numeric ", 0, 0, ACC_DISP); break;
default: display("?????????", 0, 0, ACC_DISP); break;
}
display(" Size: ", 0, 0, high);
if (format[line].dbf_type == 'N')
sprintf(text,"%3u %u",format[line].dbf_len, format[line].dbf_dec);
else sprintf(text, "%3u ", format[line].dbf_len);
display(text, 0, 0, ACC_DISP); display(" ", line+1, 45, low);
} /* end function linedisp */
/*
*
* Function to validate a dbase3+ field name
*
*/
int dbf_name (name)
byte *name;{
int z, len;
concat(name, 0); /* strip trailing spaces */
strupr(name); /* turn alpha characters into uppercase */
len = strlen(name);
if (len > 10 || !len || !isalpha(name[0])) goto error;
for (z = 1 ; z < len ; z++)
if (!isalpha(name[z]) && !isdigit(name[z]) && name[z] != '_')
goto error;
return 1;
error: disp_err("Invalid character in fieldname",3);
return 0;
}
/*
*
* Function to accept a new line in dictionary
*
*/
#define CR_MSG0 " "
#define CR_MSG1 " Char, Date, Logical, Numeric "
#define CR_MSG2 " Maximum of 254 bytes in size "
#define CR_MSG3 " Maximum of 32 bytes in Numeric"
#define CR_MSG4 " Maximum of 8 decimal places "
#define CR_MSG5 " Only A - Z, 0 - 9, and _ "
int lineacpt(format, fld)
struct DBF_DEF *format;
int fld;{
int ret, ans, z;
char text[12];
/* */
name: display(CR_MSG5, fld+1, 48, low);
set_crsr(fld+1, 7);
ret = accept(format[fld].dbf_name, left, alt_reverse, 10, 0);
if (ret && INCHAR != CRS_RT) goto end;
if (!dbf_name(format[fld].dbf_name)) goto name;
display(format[fld].dbf_name, fld+1, 7, ACC_DISP);
for (z = 0 ; z < 20 ; z++)
if (z != fld && !strcmp((byte*)format[fld].dbf_name,
(byte*)format[z].dbf_name))
{disp_err("Duplicate name",3); goto name;}
/* */
type: display(CR_MSG1, fld+1, 48, low);
set_crsr(fld+1, 25);
text[0] = format[fld].dbf_type; text[1] = 0;
ret = accept(text, left, alt_reverse, 1, 0);
if (ret) if (INCHAR == CTL_ENT || INCHAR == CRS_LT) goto name;
else if (INCHAR != CRS_RT) goto end;
format[fld].dbf_type = text[0] = toupper(text[0]);
/* */
switch ((int)text[0]){
case 'C': display("Character", fld+1, 25, ACC_DISP);
sprintf(text, "%3u", format[fld].dbf_len);
c_size: display(CR_MSG2, fld+1, 48, low);
set_crsr(fld+1, 42);
ret = accept(text, code, alt_low, 3, 0);
if (ret) if (INCHAR == CTL_ENT || INCHAR == CRS_LT)
goto type;
else break;
if ((ans = atoi(text)) > 254 || !ans)
{disp_err("size must be 1 thru 254", 1); goto c_size;}
format[fld].dbf_len = ans;
break;
case 'D': break;
case 'L': break;
case 'N': display("Numeric ", fld+1, 25, ACC_DISP);
n1_size: sprintf(text, "%3u", format[fld].dbf_len);
display(CR_MSG3, fld+1, 48, low);
set_crsr(fld+1, 42);
ret = accept(text, code, alt_low, 3, 0);
if (ret) if (INCHAR == CTL_ENT || INCHAR == CRS_LT)
goto type;
else if (INCHAR != CRS_RT) break;
if ((ans = atoi(text)) > 32 || !ans)
{disp_err("size must be 1 thru 32", 1); goto n1_size;}
format[fld].dbf_len = ans;
n2_size: sprintf(text, "%1u", format[fld].dbf_dec);
display(CR_MSG4, fld+1, 48, low);
set_crsr(fld+1, 46);
ret = accept(text, code, alt_low, 1, 0);
if (ret) if (INCHAR == CTL_ENT || INCHAR == CRS_LT)
goto n1_size;
else break;
if ((ans = atoi(text)) > 8)
{disp_err("Maximum of 8 decimal places", 1);
goto n2_size;}
format[fld].dbf_dec = ans;
break;
default: disp_err("Invalid type selection", 1); goto type;
} /* end switch */
/* exit validation */
end: if (!format[fld].dbf_name[0]) return ret; /* empty */
switch((int)format[fld].dbf_type){
case 'C': format[fld].dbf_dec = 0;
if (format[fld].dbf_len == 255) goto c_size;
break;
case 'D': format[fld].dbf_len = 8;
format[fld].dbf_dec = 0; break;
case 'L': format[fld].dbf_len = 1;
format[fld].dbf_dec = 0; break;
case 'N': if (format[fld].dbf_len > 32) goto n1_size;
if (format[fld].dbf_dec > 8) goto n2_size;
if (format[fld].dbf_dec + 2 > format[fld].dbf_len)
goto n1_size;
break;
default: goto type;
} /* end switch */
display(CR_MSG0, fld+1, 48, low); /* blank out help area */
if (!format[fld].dbf_len) memset(format[fld].dbf_name, 0, 11);
linedisp(format, fld);
return ret;
} /* end function lineacpt */
/*
*
* Function to shuffle up and down the dictionary display
*
*/
void lineshuf(format, fld, up)
struct DBF_DEF *format;
int fld, up;{
int to, from, base;
up = (up < 0 ? -1 : 1);
scroll(up, fld); /* scroll window up or down */
to = (up > 0 ? fld : 19);
from = (up > 0 ? fld + 1 : 18);
base = (up > 0 ? 19 : fld);
for (; base != to ; to += up, from += up){
memcpy(format[to].dbf_name, format[from].dbf_name, 11);
format[to].dbf_type = format[from].dbf_type;
format[to].dbf_len = format[from].dbf_len;
format[to].dbf_dec = format[from].dbf_dec;
}
memset(format[to].dbf_name, 0, 11);
format[to].dbf_type = 'C';
format[to].dbf_len = 0;
format[to].dbf_dec = 0;
if (up < 0) linedisp(format, fld);
} /* end function lineshuf */
/*
*
* Main section
*
*/
void main(){
char name[51];
int z, fh;
clr_scrn("dBase3+ dictionary create");
strcpy(name, "dbftest.dbf");
for (;;){
for (z = 0 ; z < 8 ; KEYMATCH[z++] = 0); disp_err("",1);
display("Enter file name ", 20, 2, low);
if (accept(name, left, alt_reverse, 50, 0)) goodbye(0);
if ((fh = fileopen(name, dbase3, readonly)) < 0) continue;
if (fh && FN[fh].fnext != NULL
&& !disp_qry("Do you wish to overwrite file"))
{fileclos(fh); continue;}
else if (fh) {fileclos(fh); if (fileback(name) < 1) continue;}
if (!dbf_cr(name)) {name[0] = 0; disp_err("Dictionary created", 1);}
else disp_err("Error end to dict create", 2);
}
}